package util.http;

import com.alibaba.fastjson.JSON;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.entity.mime.MultipartEntityBuilder;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.context.ContextLoader;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import util.string.StringUtil;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.InputStream;
import java.util.*;

/**
 * http工具类  实现远程调用
 *
 * @Author zt
 * @date 2021/11/11 9:12
 * @Version 1.0
 */
public class HttpUtil {

    /**
     * GET请求
     *
     * @param url url地址
     * @return 响应结果
     * @throws Exception 异常
     */
    public static String doGet(String url) throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet get = new HttpGet(url);
        CloseableHttpResponse response = httpClient.execute(get);
        HttpEntity entity = response.getEntity();
        String result = EntityUtils.toString(entity, "utf-8");
        response.close();
        httpClient.close();
        return result;
    }

    /**
     * Get请求
     *
     * @param url     url地址
     * @param headers 头文件
     * @return 响应结果
     * @throws Exception 异常
     */
    public static String doGet(String url, Map<String, String> headers) throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet get = new HttpGet(url);
        if (headers != null) {
            for (String key : headers.keySet()) {
                get.setHeader(key, headers.get(key));
            }
        }
        CloseableHttpResponse response = httpClient.execute(get);
        HttpEntity entity = response.getEntity();
        String result = EntityUtils.toString(entity, "utf-8");
        response.close();
        httpClient.close();
        return result;
    }

    /**
     * Get 请求
     *
     * @param url  url地址
     * @param list 参数
     * @return 响应数据
     * @throws Exception 异常
     */
    public static String doGet(String url, List<NameValuePair> list) throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        URIBuilder builder = new URIBuilder(url);
        builder.setParameters(list);
        HttpGet get = new HttpGet(builder.build());
        CloseableHttpResponse response = httpClient.execute(get);
        HttpEntity entity = response.getEntity();
        String result = EntityUtils.toString(entity, "utf-8");
        response.close();
        httpClient.close();
        return result;
    }

    /**
     * Post 请求
     *
     * @param url url地址
     * @return 响应数据
     * @throws Exception 异常
     */
    public static String doPost(String url) throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost post = new HttpPost(url);
        CloseableHttpResponse response = httpClient.execute(post);
        HttpEntity entity = response.getEntity();
        String result = EntityUtils.toString(response.getEntity(), "utf-8");
        response.close();
        httpClient.close();
        return result;
    }

    /**
     * Post 请求
     *
     * @param url  url地址
     * @param list 参数
     * @return 响应数据
     * @throws Exception 异常
     */
    public static String doPost(String url, List<NameValuePair> list) throws Exception {

        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpPost post = new HttpPost(url);
        StringEntity entity = new UrlEncodedFormEntity(list, "utf-8");
        post.setEntity(entity);
        CloseableHttpResponse response = httpClient.execute(post);
        String result = EntityUtils.toString(response.getEntity(), "utf-8");
        response.close();
        httpClient.close();
        return result;
    }

    /**
     * Post
     *
     * @param url     url 地址
     * @param json    参数
     * @param headers 头文件
     * @return 响应参数
     * @throws Exception 异常
     */
    public static String doPost(String url, Map<String, Object> json, Map<String, String> headers) throws Exception {
        String jsonStr=  JSON.toJSONString(json);
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        // 创建Http Post请求
        HttpPost httpPost = new HttpPost(url);
        if (headers != null) {
            for (String key : headers.keySet()) {
                httpPost.setHeader(key, headers.get(key));
            }
        }
        // 创建请求内容
        StringEntity entity = new StringEntity(jsonStr, ContentType.APPLICATION_JSON);
        httpPost.setEntity(entity);
        // 执行http请求
        response = httpClient.execute(httpPost);
        resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        response.close();
        return resultString;
    }

    /**
     * Post 请求
     *
     * @param url  url地址
     * @param json 参数
     * @return 响应数据
     * @throws Exception 异常
     */
    public static String doPost(String url,String json) throws Exception {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";

        // 创建Http Post请求
        HttpPost httpPost = new HttpPost(url);
        // 创建请求内容
        StringEntity entity = new StringEntity(json, ContentType.APPLICATION_JSON);
        httpPost.setEntity(entity);
        // 执行http请求
        response = httpClient.execute(httpPost);
        resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        response.close();
        return resultString;
    }

    /**
     * Post 请求
     *
     * @param url  url地址
     * @param json 参数
     * @return 响应数据
     * @throws Exception 异常
     */
    public static String doPost(String url,Map<String, Object> json) throws Exception {
        String jsonStr=  JSON.toJSONString(json);
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";

        // 创建Http Post请求
        HttpPost httpPost = new HttpPost(url);
        // 创建请求内容
        StringEntity entity = new StringEntity(jsonStr, ContentType.APPLICATION_JSON);
        httpPost.setEntity(entity);
        // 执行http请求
        response = httpClient.execute(httpPost);
        resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        response.close();
        return resultString;
    }

    /**
     * Post 请求
     *
     * @param url         url地址
     * @param inputStream 输入流
     * @param name        请求名
     * @param fileName    文件名
     * @return 响应数据
     * @throws Exception 异常
     */
    public static String doPost(String url, InputStream inputStream, String name, String fileName) throws Exception {
        // 创建Httpclient对象
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        // 创建Http Post请求
        HttpPost post = new HttpPost(url);
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.addBinaryBody(name, inputStream, ContentType.MULTIPART_FORM_DATA, fileName);
        HttpEntity entity = builder.build();
        // 创建请求内容
        post.setEntity(entity);
        // 执行http请求
        response = httpClient.execute(post);
        resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        response.close();
        inputStream.close();

        return resultString;
    }

    /**
     * Put 请求
     *
     * @param url     url 地址
     * @param headers 头文件
     * @param json    参数
     * @return 响应数据
     * @throws Exception 异常
     */
    public static String doPut(String url, Map<String, String> headers, Map<String,Object> json) throws Exception {
        String jsonStr=  JSON.toJSONString(json);
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        HttpPut httpPut = new HttpPut(url);
        if (headers != null) {
            for (String key : headers.keySet()) {
                httpPut.setHeader(key, headers.get(key));
            }
        }
        StringEntity entity = new StringEntity(jsonStr, ContentType.APPLICATION_JSON);
        httpPut.setEntity(entity);
        response = httpClient.execute(httpPut);
        resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        response.close();
        return resultString;
    }


    /**
     * Put 请求
     *
     * @param url         url地址
     * @param headers     头文件
     * @param inputStream 输入流
     * @param fileName    文件名
     * @return 响应数据
     * @throws Exception 异常
     */
    public static String doPut(String url, Map<String, String> headers, InputStream inputStream, String fileName) throws Exception {
        CloseableHttpClient httpClient = HttpClients.createDefault();
        CloseableHttpResponse response = null;
        String resultString = "";
        HttpPut httpPut = new HttpPut(url);
        if (headers != null) {
            for (String key : headers.keySet()) {
                httpPut.setHeader(key, headers.get(key));
            }
        }
        MultipartEntityBuilder builder = MultipartEntityBuilder.create();
        builder.addBinaryBody("file", inputStream, ContentType.MULTIPART_FORM_DATA, fileName);
        HttpEntity entity = builder.build();
        httpPut.setEntity(entity);
        response = httpClient.execute(httpPut);
        resultString = EntityUtils.toString(response.getEntity(), "utf-8");
        response.close();
        inputStream.close();
        return resultString;
    }

    /**
     * 获取 request
     * @return request
     */
    public static HttpServletRequest getRequest() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
    }

    /**
     * 获取session
     * @return session
     */
    public static HttpSession getSession() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getSession();
    }

    /**
     *  获取 response
     * @return response
     */
    public static HttpServletResponse getResponse() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getResponse();
    }

    /**
     * 获取 context
     * @return context
     */
    public static ServletContext getContext() {
        return ContextLoader.getCurrentWebApplicationContext().getServletContext();
    }
    /**
     * 获取 application
     * @return application
     */
    protected ServletContext getApplication() {
        return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest().getSession().getServletContext();
    }

    /**
     * 获取项目名称路径
     * @return 项目名称路径
     */
    public static String getContentpath() {
        return getRequest().getContextPath();
    }

    /**
     * 获取项目绝对路径
     * @return 项目绝对路径
     */
    public static String getRealPath() {
        return getRequest().getSession().getServletContext().getRealPath("/");
    }


    /**
     * 获取简单域名
     * @return 域名
     */
    public static String getDomain(){
        HttpServletRequest request = getRequest();
        StringBuffer url = request.getRequestURL();
        return url.delete(url.length() - request.getRequestURI().length(), url.length()).toString();
    }

    /**
     * 获取完整域名
     * @return 域名
     */
    public static String getOrigin(){
        HttpServletRequest request = getRequest();
        return request.getHeader("Origin");
    }

    /**
     * 根据name 获取请求中的值
     * @param name 参数名
     * @param defaultValue 默认值
     * @return  值
     */
    public String getParameter(String name, String defaultValue) {
        String resultStr = getRequest().getParameter(name);
        if (resultStr == null || "".equals(resultStr) || "null".equals(resultStr) || "undefined".equals(resultStr)) {
            return defaultValue;
        } else {
            return resultStr;
        }
    }

    /**
     * 根据name 获取请求中的值,无默认值
     * @param name  参数名
     * @return
     */
    public static String getParameter(String name) {
        HttpServletRequest request = getRequest();
        if (request == null){
            return null;
        }
        return request.getParameter(name);
    }

    /**
     * 获取所有request请求参数key-value
     * @param request 请求
     * @return 参数集合
     */
    public static Map<String, String> getRequestParams(HttpServletRequest request) {
        Map<String, String> params = new HashMap<String, String>();
        if (null != request) {
            Set<String> paramsKey = request.getParameterMap().keySet();
            for (String key : paramsKey) {
                params.put(key, request.getParameter(key));
            }
        }
        return params;
    }


    /**
     * 获取请求basePath
     * @param request 请求
     * @return 路径
     */
    public static String getBasePath(HttpServletRequest request) {
        StringBuffer basePath = new StringBuffer();
        String scheme = request.getScheme();
        String domain = request.getServerName();
        int port = request.getServerPort();
        basePath.append(scheme);
        basePath.append("://");
        basePath.append(domain);
        if ("http".equalsIgnoreCase(scheme) && 80 != port) {
            basePath.append(":").append(String.valueOf(port));
        } else if ("https".equalsIgnoreCase(scheme) && port != 443) {
            basePath.append(":").append(String.valueOf(port));
        }
        return basePath.toString();
    }

    /**
     * 获取 ip地址
     * @param request
     * @return  ip地址
     */
    public static String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("X-Forwarded-For");
        if (StringUtil.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            if(ip.indexOf("::ffff:")!=-1) ip = ip.replace("::ffff:", "");
            int index = ip.indexOf(",");
            if (index != -1) {
                return ip.substring(0, index);
            } else {
                return ip;
            }
        }
        ip = request.getHeader("X-Real-IP");
        if (StringUtil.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)) {
            return ip;
        }
        return request.getRemoteAddr();
    }

    /**
     * 判断当前请求是否为Ajax
     * @param request
     * @return  判断结果
     */
    public static boolean isAjaxRequest(HttpServletRequest request) {
        String header = request.getHeader("X-Requested-With");
        return !StringUtils.isEmpty(header) && "XMLHttpRequest".equals(header);
    }


    /**
     * 移除request指定参数
     * @param request
     * @param paramName 参数名
     * @return 移除后的String
     */
    public String removeParam(HttpServletRequest request, String paramName) {
        String queryString = "";
        Enumeration keys = request.getParameterNames();
        while (keys.hasMoreElements()) {
            String key = (String) keys.nextElement();
            if (key.equals(paramName)) {
                continue;
            }
            if ("".equals(queryString)) {
                queryString = key + "=" + request.getParameter(key);
            } else {
                queryString += "&" + key + "=" + request.getParameter(key);
            }
        }
        return queryString;
    }


}
